package com.promis.crypto.asymmetric;

import com.promis.crypto.KeyCipher;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

public class AsymmetricKeyCipher extends KeyCipher {

	public AsymmetricKeyCipher(String keyAlgorithm, String cipherAlgorithm) {
		super(keyAlgorithm, cipherAlgorithm);
	}
	
	public KeyPair createKeyPair(int keySize) throws Exception {
		KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyAlgorithm);
		keyPairGenerator.initialize(keySize);
		return keyPairGenerator.generateKeyPair();
	}
	
	public PrivateKey toPrivateKey(byte[] privateKey) throws Exception {
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
		KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
		return keyFactory.generatePrivate(pkcs8KeySpec);
	}
	
	public PublicKey toPublicKey(byte[] publicKey) throws Exception {
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey);
		KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
		return keyFactory.generatePublic(x509KeySpec);
	}
	
	public byte[] toPrivateKey(PrivateKey privateKey) {
		return privateKey.getEncoded();
	}
	
	public byte[] toPublicKey(PublicKey publicKey) {
		return publicKey.getEncoded();
	}
	
	public byte[] encryptByPublicKey(byte[] data, PublicKey publicKey) throws Exception {  
	    return cipher(Cipher.ENCRYPT_MODE, data, publicKey);
	}
	
	public byte[] decryptByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception {
		return cipher(Cipher.DECRYPT_MODE, data, privateKey);
	}
	
	public byte[] encryptByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception {  
	    return cipher(Cipher.ENCRYPT_MODE, data, privateKey);
	}
	
	public byte[] decryptByPublicKey(byte[] data, PublicKey publicKey) throws Exception {
		return cipher(Cipher.DECRYPT_MODE, data, publicKey);
	}
	
//	public static void main(String[] args) throws Exception {
//		AsymmetricKeyCipher keyCipher = new AsymmetricKeyCipher("RSA", "RSA");
//		KeyPair keyPair = keyCipher.createKeyPair(1024);
//		
////		System.out.println(keyPair.getPrivate().getFormat());
//		byte[] privateKey = keyCipher.toPrivateKey(keyPair.getPrivate());
//		keyCipher.toPrivateKey(privateKey);
//		
//		byte[] publicKey = keyCipher.toPublicKey(keyPair.getPublic());
//		keyCipher.toPublicKey(publicKey);
//	}
}
